/*LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
 銆愬钩    鍙般�戝寳浜緳閭辨櫤鑳界鎶�TC297TX鏍稿績鏉�
 銆愮紪    鍐欍�慫YF/chiusir
 銆怑-mail  銆慶hiusir@163.com
 銆愯蒋浠剁増鏈�慥1.1 鐗堟潈鎵�鏈夛紝鍗曚綅浣跨敤璇峰厛鑱旂郴鎺堟潈
 銆愭渶鍚庢洿鏂般��2023骞�1鏈�9鏃�
 銆愮浉鍏充俊鎭弬鑰冧笅鍒楀湴鍧�銆�
 銆愮綉    绔欍�慼ttp://www.lqist.cn
 銆愭窐瀹濆簵閾恒�慼ttp://longqiu.taobao.com
 ------------------------------------------------
 銆恉ev.env.銆慉URIX Development Studio1.3鐗堟湰
 銆怲arget 銆� TC297TX
 銆怌rystal銆� 20.000Mhz
 銆怱YS PLL銆� 300MHz
 ________________________________________________________________

 QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ*/
/******************************************************************************/
#include "include.h"

unsigned char Image_Data[IMAGEH][IMAGEW];   //瀛樻斁鍘熷鍥惧儚
uint16_t Image_Use[LCDH][LCDW];              //鍘嬬缉鍚庝箣鍚庣敤浜庡瓨鏀惧睆骞曟樉绀烘暟鎹�
uint8_t Image_Bin[LCDH][LCDW];

int16_t OV7725_E;
image_RGB565 Image_RGB565[LCDH][LCDW];
uint8_t B_min,B_max,R_min,R_max,G_min,G_max;
uint16_t WhitePoint_Value;//涓�寮犲浘鐗囷紝鐧界偣鐨勬�绘暟

/*************************************************************************
*  鍑芥暟鍚嶇О锛歄V7725_Init
*  鍔熻兘璇存槑锛歄V7725鍒濆鍖栧嚱鏁�
*  鍙傛暟璇存槑锛歠ps锛氬抚鐜囷紙鏆傛椂鏈�澶у��15锛�
*  鍑芥暟杩斿洖锛氭棤
*  淇敼鏃堕棿锛�2022骞�12鏈�29鏃�
*  澶�    娉細G
*************************************************************************/
void OV7725_Init(uint8_t fps)
{
    uint8_t id[2];    //鐎涙ɑ鏂侀幗鍕剼婢剁d
    uint16_t width = OV7725_IMAGEW, height = OV7725_IMAGEH;
    uint16_t hstart, vstart, hsize;
    char txt[16];

    /*SCCB閫氫俊鍒濆鍖�*/
    SCCB_Init();

    /*澶嶄綅OV7725*/
    OV7725_SoftwareReset();

    /*寤舵椂鏈�灏�2姣*/
    delayms(5);

    /*7725鏈�澶у儚绱犱负 480*640 */
    if ((OV7725_IMAGEW > 640) || (OV7725_IMAGEH > 480))
    {
        TFTSPI_P8X16Str(0,2,"7725 dpi!!",u16RED,u16BLUE);
        while(1);
    }
    SCCB_RegRead_Int8(OV7725_SCCB_ADDR,OV7725_PID_REG,&id[0]);  //璇诲彇璁惧ID楂樺叓浣�
    SCCB_RegRead_Int8(OV7725_SCCB_ADDR,OV7725_VER_REG,&id[1]);  //璇诲彇璁惧ID浣庡叓浣�
    sprintf(txt, "ID:%02x %02x", id[0], id[1]);
    TFTSPI_P8X16Str(0,3,txt,u16RED,u16BLUE);
    if(OV7725_REVISION != (((uint32_t)id[0] << 8U) | (uint32_t)id[1]))//鍒ゆ柇璇诲彇鐨処D鏄惁姝ｇ‘
    {
        TFTSPI_P8X16Str(0,2,"7725 NG",u16RED,u16BLUE);
        while(1){

        }
    }else{
        TFTSPI_P8X16Str(0,2,"7725 OK",u16RED,u16BLUE);
    }
    delayms(500);   //寤舵椂鐨勪富瑕佷綔鐢ㄦ槸鏌ョ湅璇诲彇缁撴灉

    OV7725_Init_Regs(); //鍏堟寜瀹樻柟鐨勫垵濮嬪寲鏂瑰紡鍒濆鍖栨憚鍍忓ご 鍚庣画鍐嶆敼鍔�

    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM2_REG, 0x03);  //COM2鎺у埗    杞潯鐪犳ā寮� Bit[4]  杈撳嚭椹卞姩鑳藉姏 Bit[1:0]: 00: 1x 01: 2x 10: 3x 11: 4x

#if 1    //RGB565 鏍煎紡鏁版嵁
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM7_REG, 0x46);  // 杈撳嚭鍍忕礌澶у皬QVGA锛�240*320锛� 鏁版嵁鏍煎紡RGB565
                                                                 /* OV7725_COM7_REG
                                                                    Bit[7]: 灏嗘墍鏈夊瘎瀛樺櫒閲嶇疆涓洪粯璁ゅ��
                                                                    0: 涓嶅彉
                                                                    1: 灏嗘墍鏈夊瘎瀛樺櫒閲嶇疆涓洪粯璁ゅ��
                                                                    Bit[6]: 閫夋嫨鍒嗚鲸鐜�
                                                                    0: VGA
                                                                    1: QVGA
                                                                    Bit[5]: BT.656閫夋嫨寮�鍏�
                                                                    Bit[4]: Sensor RAW
                                                                    Bit[3:2]: RGB杈撳嚭鏍煎紡
                                                                    00: GBR4:2:2
                                                                    01: RGB565
                                                                    10: RGB555
                                                                    11: RGB444
                                                                    Bit[1:0]: 杈撳嚭鏍煎紡鎺у埗
                                                                    00: YUV
                                                                    01: Processed Bayer RAW
                                                                    10: RGB
                                                                    11: Bayer RAW */
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM3_REG, 0x00); //Bit[6]: 姘村钩闀滃儚鎺у埗 0姘村钩闀滃儚鍏� 1姘村钩闀滃儚寮�
                                                                //Bit[5]: 鍦≧GB杈撳嚭妯″紡涓嬩氦鎹/R杈撳嚭搴忓垪
                                                                //Bit[4]: 鍦╕uV杈撳嚭妯″紡涓嬩氦鎹/uV杈撳嚭搴忓垪   (鍙傝瀵勫瓨鍣―SP Ctrl3[71 (Ox66))
                                                                //Bit[3]: 浜ゆ崲杈撳嚭MSB/LSB
    hstart = (0x3fU << 2U);     //鍥惧儚姘村钩寮�濮嬩綅缃�
    vstart = (0x03U  << 1U) ;   //鍥惧儚鍨傜洿寮�濮嬩綅缃�
#else   //
    /*OV7725_COM7_REG
    Bit[7]: 閲嶇疆瀵勫瓨鍣�
    0: 涓嶉噸缃�
    1: 灏嗘墍鏈夊瘎瀛樺櫒閲嶇疆涓洪粯璁ゅ��
    Bit[6]: 鍒嗚鲸鐜囪缃紙7725杈撳嚭鏀寔涓ょ鍒嗚鲸鐜囷紝鍏朵粬鐨勪换鎰忚嚜瀹氫箟鍒嗚鲸鐜囩浉褰撲簬鎴彇杩欎袱绉嶅垎杈ㄧ巼鍏朵腑鐨勪竴閮ㄥ垎锛屼細涓㈠け瑙嗛噹锛�
    0: VGA
    1: QVGA
    Bit[5]: BT.656鍗忚寮�/鍏抽�夋嫨
    Bit[4]: 浼犳劅鍣ㄧ殑鍘熷鍊�
    Bit[3:2]: RGB杈撳嚭鏍煎紡鎺т欢
    00: GBR4:2:2
    01: RGB565
    10: RGB555
    11: RGB444
    Bit[1:0]: 杈撳嚭鏍煎紡鎺у埗
    00: YUV
    01: Processed Bayer RAW
    10: RGB
    11: Bayer RAW */
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM7_REG, 0x43);  //  娴ｈ法鏁VGA 閸滐拷 Bayer RAW 閺嶇厧绱�

    //Bit[6]: 0姘村钩闀滃儚鍏� 1姘村钩闀滃儚寮�  娉ㄦ剰寮�鍚按骞抽暅鍍忔椂鏈�濂藉紑鍚�0x32瀵勫瓨鍣ㄧ殑Bit[7]:闀滃儚鍥惧儚杈圭紭瀵归綈-鍦ㄩ暅鍍忔ā寮忎笅搴旇璁剧疆涓�1
    //Bit[4]: 0 UYVY妯″紡  1 YUYV妯″紡
    //Bit[3]: 澶у皬绔�
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM3_REG, 0x00);

    hstart = 0x3fU << 2U;   //閸ユ儳鍎氬鏉戦挬瀵拷婵缍呯純锟�
    vstart = 0x03U << 1U;   //閸ユ儳鍎氶崹鍌滄纯瀵拷婵缍呯純锟�
#endif
    /*Bit[1:0]: Output selection
      00: YUV or RGB
      01: YUV or RGB
      10: RAW8
      11: RAW10*/
//    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_DSP_CTRL4_REG, 0x4a);

    /*Bit[7]: 鍚敤蹇�烝GC/AEC绠楁硶
    Bit[6]: AEC -姝ラ暱闄愬埗
    0: 姝ラ暱闄愪簬鍨傜洿绌虹櫧
    1: 鏃犻檺鐨勬闀�
    Bit[5]: 甯﹁繃婊ゅ紑/鍏�
    Bit[4]: 鍚敤浣庝簬鏉″甫鍊肩殑AEC
    0: 灏嗘洕鍏夋椂闂撮檺鍒跺湪1/100鎴�1/120
            鍏舵鍦ㄤ换浣曞厜鐓ф潯浠朵笅褰撳惎鐢ㄥ甫閫氭护娉㈠櫒
    1: 鍏佽鏇濆厜鏃堕棿灏忎簬1/100鎴�1/120
            鍏舵鍦ㄥ己鍏夋潯浠朵笅褰撳惎鐢ㄥ甫閫氭护娉㈠櫒
    Bit[3]: 鑹ソ鐨凙EC寮�/鍏虫帶鍒�
    0: 闄愬埗鏈�灏忔洕鍏夋椂闂翠负涓�琛�
    1: 鍏佽鏇濆厜鏃堕棿灏忎簬涓�琛�
    Bit[2]: 鑷姩澧炵泭鎺у埗浣�
    0: 鎵嬪姩妯″紡
    1: 鑷姩妯″紡
    Bit[1]: AWB Enable
    0: 鎵嬪姩妯″紡
    1: 鑷姩妯″紡
    Bit[0]: AEC Enable
    0: 鎵嬪姩妯″紡
    1: 鑷姩妯″紡*/
//    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM8_REG, 0xff);

    /*瀵规瘮搴﹁缃� 褰掍竴鍖栧�间负0x20  瓒婂皬瀵规瘮搴﹁秺澶�*/
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_CNST_REG, 0x20);
    SCCB_RegWrite(OV7725_SCCB_ADDR,OV7725_BRIGHT_REG, 0x10);/*浜害璁剧疆*/
    SCCB_RegWrite(OV7725_SCCB_ADDR,OV7725_SIGN_REG, 0x10);/*浜害璁剧疆*/

    OV7725_SetFPS(fps);

    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR, OV7725_EXHCL_REG, 0x00); //铏氭嫙鍍忕礌鎻掑叆LSB鐢ㄤ簬鍦ㄦ按骞虫柟鍚戞彃鍏ヨ櫄鎷熷儚绱犵殑LSB
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR, OV7725_ADVFL_REG, 0x00); //鍨傜洿鍚屾鎻掑叆铏氭嫙琛�(1浣嶇瓑浜�1琛�)鐨凩SB
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR, OV7725_ADVFH_REG, 0x00); //鍨傜洿鍚屾鎻掑叆铏氭嫙琛岀殑MSB
    /* Resolution and timing. */
    hsize = width + 16;

    /* 璁剧疆杈撳嚭鍥剧墖澶у皬. */

    //姘村钩璧峰浣嶇疆楂樹綅  鍥犱负瀵勫瓨鍣ㄦ槸8浣嶇殑 鏈�澶�255锛屽儚绱犳渶澶�640 * 480 鏀句笉涓嬶紝鐢ㄤ簡10浣嶆暟鎹紝杩欓噷鏄珮8浣嶏紝鍓╀笅鐨勪袱浣嶆斁鍦∣V7725_HREF_REG涓�
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_HSTART_REG, hstart >> 2U);

    //姘村钩瀹藉害楂樹綅      鍥犱负瀵勫瓨鍣ㄦ槸8浣嶇殑 鏈�澶�255锛屽儚绱犳渶澶�640 * 480 鏀句笉涓嬶紝鐢ㄤ簡10浣嶆暟鎹紝杩欓噷鏄珮8浣嶏紝鍓╀笅鐨勪袱浣嶆斁鍦∣V7725_HREF_REG涓�
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_HSIZE_REG, hsize >> 2U);

    //鍨傜洿璧峰浣嶇疆楂樹綅  鍥犱负瀵勫瓨鍣ㄦ槸8浣嶇殑 鏈�澶�255锛屽儚绱犳渶澶�640 * 480 鏀句笉涓嬶紝鐢ㄤ簡9浣嶆暟鎹紝杩欓噷鏄珮8浣嶏紝鍓╀笅鐨勪袱浣嶆斁鍦∣V7725_HREF_REG涓�
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_VSTART_REG, vstart >> 1U);

    //鍨傜洿楂樺害楂樹綅      鍥犱负瀵勫瓨鍣ㄦ槸8浣嶇殑 鏈�澶�255锛屽儚绱犳渶澶�640 * 480 鏀句笉涓嬶紝鐢ㄤ簡9浣嶆暟鎹紝杩欓噷鏄珮8浣嶏紝鍓╀笅鐨勪袱浣嶆斁鍦∣V7725_HREF_REG涓�
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_VSIZE_REG, height >> 1U);

    //姘村钩杈撳嚭瀹藉害楂樹綅  鍥犱负瀵勫瓨鍣ㄦ槸8浣嶇殑 鏈�澶�255锛屽儚绱犳渶澶�640 * 480 鏀句笉涓嬶紝鐢ㄤ簡10浣嶆暟鎹紝杩欓噷鏄珮8浣嶏紝鍓╀笅鐨勪袱浣嶆斁鍦∣V7725_EXHCH_REG涓�
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_HOUTSIZE_REG, width >> 2U);

    //鍨傜洿杈撳嚭楂樺害楂樹綅  鍥犱负瀵勫瓨鍣ㄦ槸8浣嶇殑 鏈�澶�255锛屽儚绱犳渶澶�640 * 480 鏀句笉涓嬶紝鐢ㄤ簡9浣嶆暟鎹紝杩欓噷鏄珮8浣嶏紝鍓╀笅鐨勪袱浣嶆斁鍦∣V7725_EXHCH_REG涓�
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_VOUTSIZE_REG, height >> 1U);

    //姘村钩瀹藉害鍜屽瀭鐩撮珮搴︾殑浣庝綅
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_HREF_REG,
                    ((vstart & 1U) << 6U) | ((hstart & 3U) << 4U) | ((height & 1U) << 2U) | ((hsize & 3U) << 0U));

    //姘村钩杈撳嚭鍜屽瀭鐩磋緭鍑虹殑浣�2浣嶅拰浣�1浣�
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_EXHCH_REG, ((height & 1U) << 2U) | ((width & 3U) << 0U));

    OV7725_LightModeConfigs(3);
}

/*------------------------------------------------------------------------------------------------------
銆愬嚱    鏁般�慜V7725_SetFPS
銆愬姛    鑳姐�戣缃瓼PS
銆愬弬    鏁般�慺ps
銆愯繑 鍥� 鍊笺�戞棤
銆愬疄    渚嬨��
銆愭敞鎰忎簨椤广�戦厤缃殑鏄憚鍍忓ご鐨勫抚鐜囪緭鍑猴紝甯х巼瓒婇珮锛屽崟鐗囨満鐨勬柊鑳借姹傝秺楂�
--------------------------------------------------------------------------------------------------------*/
void OV7725_SetFPS(uint8_t fps)
{
    if(fps > 75)
    {
        /* 閿佺浉鐜�8鍊嶉 婊＄獥鍙�
        Bit[7:6]: 閿佺浉鐜�嶉鍣ㄦ帶鍒�
        00: 涓嶇敤鍊嶉
        01: 4鍊嶉
        10: 6鍊嶉
        11: 8鍊嶉
        Bit[5:4]: 鑷姩鏇濆厜绐楀彛澶у皬
        00: Full window
        01: 1/2 window
        10: 1/4 window
        11: Low 2/3 window*/
        SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM4_REG, 0xC1);  //PCLK 48M
    }
    else
    {
        SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM4_REG, 0x41);  //PCLK 24M
    }
    uint16_t dm_lnl = 0;                                               //铏氭嫙琛�
    uint8_t  div    = 1;                                               //鏃堕挓鍒嗛绯绘暟
    if(fps > 150)
    {
        fps = 150;
        div = 1;
        dm_lnl = 0;
    }
    else if(fps > 75)
    {
        div = 1;
        dm_lnl = (uint16_t)((150 - fps) / 150.0 * (OV7725_IMAGEH + 36*(div + 1)));
    }
    else if(fps > 50)
    {
        div = 1;
        dm_lnl = (uint16_t)((75 - fps) / 75.0 * (OV7725_IMAGEH + 36*(div + 1)));
    }
    else if(fps > 37)
    {
        div = 2;
        dm_lnl = (uint16_t)((50 - fps) / 50.0 * (OV7725_IMAGEH + 36*(div + 1)));
    }
    else if(fps > 18)
    {
        div = 3;
        dm_lnl = (uint16_t)((37.5 - fps) / 37.5 * (OV7725_IMAGEH + 36*(div + 1)));
    }
    else
    {
        div = 14;
        dm_lnl = 0;
    }
    /*鏃堕挓閰嶇疆 鏃堕挓 = PCLK * 4 / 锛堬紙1+1锛�*4锛� 鏃堕挓瓒婇珮锛屽抚鐜囪秺蹇� 涓嶈繃DMA鍙兘鎺ュ彈涓嶄簡浼氭湁鍣偣
    Bit[6]: 鐩存帴浣跨敤澶栭儴鏃堕挓(娌℃湁鏃堕挓棰勫埢搴﹀彲鐢�)
    Bit[5:0]: 鏃堕挓 = PCLK 脳 閿佺浉鐜�嶉鍣� /[(CLKRC[5:0] + 1) 脳 4]*/
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR, OV7725_CLKRC_REG, div);

    /*铏氭嫙琛屼綆鍏綅锛� 澧炲姞铏氭嫙琛屽彲浠ラ檷浣庡抚鐜囷紝閫傚綋娣诲姞鎶婂抚鐜囬厤缃埌鑷繁鎯宠鐨勫抚鐜�*/
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR, OV7725_DM_LNL_REG, (uint8_t)dm_lnl);

    /*铏氭嫙琛岄珮鍏綅*/
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR, OV7725_DM_LNH_REG, (uint8_t)(dm_lnl>>8));
}
/*------------------------------------------------------------------------------------------------------
銆愬嚱    鏁般�慜V7725_Init_Regs
銆愬姛    鑳姐�戣嚜鍔ㄦ洕鍏� VGA
銆愬弬    鏁般�戞棤
銆愯繑 鍥� 鍊笺�戞棤
銆愬疄    渚嬨��
銆愭敞鎰忎簨椤广��
--------------------------------------------------------------------------------------------------------*/
void OV7725_Init_Regs(void)
{
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x3d, 0x03);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x42, 0x7f);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x4d, 0x09);

    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x64, 0xff);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x65, 0x20);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x66, 0x00);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x67, 0x48);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x0f, 0xc5);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x13, 0xff);

    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x63, 0xe0);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x14, 0x11);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x22, 0x3f);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x23, 0x07);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x24, 0x40);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x25, 0x30);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x26, 0xa1);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x2b, 0x00);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x6b, 0xaa);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x0d, 0x41);

    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x90, 0x05);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x91, 0x01);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x92, 0x03);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x93, 0x00);

    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x94, 0x90);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x95, 0x8a);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x96, 0x06);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x97, 0x0b);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x98, 0x95);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x99, 0xa0);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x9a, 0x1e);

    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x9b, 0x08);

    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x9c, 0x20);

    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x9e, 0x81);

    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0xa6, 0x04);

    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x7e, 0x0c);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x7f, 0x16);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x80, 0x2a);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x81, 0x4e);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x82, 0x61);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x83, 0x6f);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x84, 0x7b);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x85, 0x86);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x86, 0x8e);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x87, 0x97);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x88, 0xa4);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x89, 0xaf);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x8a, 0xc5);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x8b, 0xd7);
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,0x8c, 0xe8);
}

/*------------------------------------------------------------------------------------------------------
銆愬嚱    鏁般�慜V7725_SoftwareReset
銆愬姛    鑳姐�戝浣嶆憚鍍忓ご 鎭㈠榛樿閰嶇疆
銆愬弬    鏁般�戞棤
銆愯繑 鍥� 鍊笺�戞棤
銆愬疄    渚嬨��
銆愭敞鎰忎簨椤广��
--------------------------------------------------------------------------------------------------------*/
void OV7725_SoftwareReset(void)
{
    SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM7_REG, 0x80);
}
/*------------------------------------------------------------------------------------------------------
銆愬嚱    鏁般�慜V7725_LightModeConfigs
銆愬姛    鑳姐�戠伅鍏夐厤缃�
銆愬弬    鏁般��0:鑷姩妯″紡1:鏅村ぉ2,澶氫簯3,鍔炲叕瀹�4,瀹堕噷5,澶滄櫄
銆愯繑 鍥� 鍊笺�戞棤
銆愬疄    渚嬨��
銆愭敞鎰忎簨椤广��
--------------------------------------------------------------------------------------------------------*/
void OV7725_LightModeConfigs(uint8_t mode)
{
    switch(mode)
    {
        case 1:  //鏅村ぉ
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM8_REG, 0xfd);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_BLUE_REG, 0x5a);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_RED_REG, 0x5c);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM5_REG, 0x65);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_ADVFL_REG, 0x00);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_ADVFH_REG, 0x00);
            break;
        case 2:  //澶氫簯
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM8_REG, 0xfd);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_BLUE_REG, 0x58);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_RED_REG, 0x60);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM5_REG, 0x65);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_ADVFL_REG, 0x00);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_ADVFH_REG, 0x00);
            break;
        case 3:  //鍔炲叕瀹�
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM8_REG, 0xfd);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_BLUE_REG, 0x84);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_RED_REG, 0x4c);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM5_REG, 0x65);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_ADVFL_REG, 0x00);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_ADVFH_REG, 0x00);
            break;
        case 4:   //瀹堕噷
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM8_REG, 0xfd);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_BLUE_REG, 0x96);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_RED_REG, 0x40);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM5_REG, 0x65);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_ADVFL_REG, 0x00);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_ADVFH_REG, 0x00);
            break;
        case 5:   //鏅氫笂
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM8_REG, 0xff);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_BLUE_REG, 0x80);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_RED_REG, 0x80);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM5_REG, 0xe5);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_ADVFL_REG, 0x00);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_ADVFH_REG, 0x00);
            break;
        default:   //鑷姩妯″紡顢�
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM8_REG, 0xff);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_BLUE_REG, 0x80);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_RED_REG, 0x80);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_COM5_REG, 0x65);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_ADVFL_REG, 0x00);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_ADVFH_REG, 0x00);
            break;
    }
}
/*------------------------------------------------------------------------------------------------------
銆愬嚱    鏁般�慜V7725_SpecialEffectConfigs
銆愬姛    鑳姐�戠壒鏁堥厤缃�
銆愬弬    鏁般��0:鏅�氭ā寮� 1.榛戠櫧 2.澶嶅彜  3,鍋忚摑4,鍋忕孩5,鍋忕豢 6,璐熺墖
銆愯繑 鍥� 鍊笺�戞棤
銆愬疄    渚嬨��
銆愭敞鎰忎簨椤广��
--------------------------------------------------------------------------------------------------------*/
void OV7725_SpecialEffectConfigs(uint8_t mode)
{
    switch(mode)
    {
        case 1:  //榛戠櫧
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_SDE_REG, 0x26);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_UFIX_REG, 0x80);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_VFIX_REG, 0x80);
            break;
        case 2:  //澶嶅彜
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_SDE_REG, 0x1e);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_UFIX_REG, 0x40);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_VFIX_REG, 0xa0);
            break;
        case 3:  //鍋忚摑
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_SDE_REG, 0x1e);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_UFIX_REG, 0xa0);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_VFIX_REG, 0x40);
            break;
        case 4:   //鍋忕孩
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_SDE_REG, 0x1e);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_UFIX_REG, 0x80);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_VFIX_REG, 0x40);
            break;
        case 5:   //鍋忕豢
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_SDE_REG, 0x1e);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_UFIX_REG, 0x60);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_VFIX_REG, 0x60);
            break;
        case 6:   //璐熺墖
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_SDE_REG, 0x46);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_UFIX_REG, 0x00);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_VFIX_REG, 0x00);
            break;
        default:   //鏅�氭ā寮�
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_SDE_REG, 0x06);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_UFIX_REG, 0x80);
            SCCB_RegWrite_Int8(OV7725_SCCB_ADDR,OV7725_VFIX_REG, 0x80);
            break;
    }
}

/***************************************************************
* @brief    TFT18灞� unsigned char 鐏板害鏁版嵁鏄剧ず
*
* @param    high_start 锛� 鏄剧ず鍥惧儚寮�濮嬩綅缃�
* @param    wide_start 锛� 鏄剧ず鍥惧儚寮�濮嬩綅缃�
* @param    high 锛� 鏄剧ず鍥惧儚楂樺害
* @param    wide 锛� 鏄剧ず鍥惧儚瀹藉害
* @param    ppic锛� 鏄剧ず鍥惧儚鏁版嵁鍦板潃
* @return   鏃�
* @note     娉ㄦ剰 灞忓箷宸︿笂涓� 锛�0锛�0锛�
* @date     2019/12/3 鏄熸湡浜�
***************************************************************/
void OV7725_TFTSPI_Road(unsigned char wide_start, unsigned char high_start, unsigned char high, unsigned char wide)
{
    unsigned long i, j;
    /* 璁剧疆鏄剧ず鑼冨洿 */
    TFTSPI_Set_Pos(wide_start, high_start, wide_start + wide - 1, high_start + high - 1);
    unsigned short color;
    /* 鏄剧ず鍥惧儚 */
    for(i = 0; i < LCDH; i++)
    {
        for(j = 0; j < LCDW; j ++)
        {
            /* 鏄剧ず */
            color = Image_RGB565[i][j].R *2*2*2*2*2*2*2*2*2*2*2 +  Image_RGB565[i][j].G *2*2*2*2*2 + Image_RGB565[i][j].B;
            TFTSPI_Write_Word (color);
        }
    }
}

//榛戠櫧鏄剧ず锛堢洰鍓嶆湭娴嬭瘯锛�
void BIN_OV7725_TFTSPI_Road(unsigned char wide_start,unsigned char high_start,unsigned char high,unsigned char wide,uint8_t ppic[LCDH][LCDW]){
    unsigned long i,j;
    TFTSPI_Set_Pos(wide_start,high_start,wide_start+wide-1,high_start+high-1);
    unsigned short color;

    for(i = 0;i<LCDH;i++){
        for(j = 0;j<LCDW;j++){
            color = ppic[i][j];
            TFTSPI_Write_Word(color*(0xFFFF));
        }
    }
}


void Ov7725_Init (unsigned char fps)
{
    //绂佹涓柇
    IfxCpu_disableInterrupts();

    /* 鍒濆鍖栨暟鎹綅 */
    PIN_InitConfig(P02_0, PIN_MODE_INPUT_PULLDOWN, 0);
    PIN_InitConfig(P02_1, PIN_MODE_INPUT_PULLDOWN, 0);
    PIN_InitConfig(P02_2, PIN_MODE_INPUT_PULLDOWN, 0);
    PIN_InitConfig(P02_3, PIN_MODE_INPUT_PULLDOWN, 0);
    PIN_InitConfig(P02_4, PIN_MODE_INPUT_PULLDOWN, 0);
    PIN_InitConfig(P02_5, PIN_MODE_INPUT_PULLDOWN, 0);
    PIN_InitConfig(P02_6, PIN_MODE_INPUT_PULLDOWN, 0);
    PIN_InitConfig(P02_7, PIN_MODE_INPUT_PULLDOWN, 0);

    OV7725_Init(fps);

    /* DMA  */
    PIN_Exti(P00_4, PIN_IRQ_MODE_FALLING);

    /* DMA */
    DMA_CameraInitConfig((unsigned long) (&MODULE_P02.IN.U), (unsigned long) Image_Data, PIN_INT2_PRIORITY);

    /* 鍦轰腑鏂�*/
    PIN_Exti(P15_1, PIN_IRQ_MODE_RISING_FALLING);//鍙岃竟娌胯Е鍙�
    /* 琛屼腑鏂�*/
    PIN_Exti(P15_8, PIN_IRQ_MODE_RISING);

    /* 寮�鍚腑鏂�*/
    IfxCpu_enableInterrupts();

}
void Get_Use_Image(void)
{
    int i = 0,j = 0;
    int div_h = IMAGEH/LCDH;            //4
    int div_w = IMAGEW/LCDW;          //8
    unsigned short color_H,color_L,color;
    for(i = 0; i  < IMAGEH; i+=div_h)   //240/2=120 闅斾竴琛屽彇涓�琛屾暟鎹�
    {
        for(j = 0;j < IMAGEW; j+=div_w) //640/4=160 闅斾竴鍒楀彇涓�鍒楁暟鎹紙姣忓洓涓儚绱犳暟鎹彇涓や釜 La Ma Lb Mb 锛�
        {
            //鍚堟垚16浣嶇殑RGB565鍍忕礌鏁版嵁
            color_L = Image_Data[i][j];
            color_H = Image_Data[i][j+1];
            color = color_H <<8 | color_L;
            Image_RGB565[i/div_h][j/div_w].R = ((color & 0xF800) >> 11);
            Image_RGB565[i/div_h][j/div_w].G = ((color & 0x07E0) >> 5);
            Image_RGB565[i/div_h][j/div_w].B = (color & 0x001F) ;
        }
    }
}



void Test_Ov7725 (void)
{
   //TFTSPI_Init(0);               //TFT1.8妯睆
   //TFTSPI_CLS(u16BLUE);          //娓呭睆 钃濊壊
    /* 鎽勫儚澶村垵濮嬪寲 */
   char txt[10];

    while (1)
    {
        uint16_t WhitePoint;
        WhitePoint = 0;

        for(int i = 0;i<LCDH;i++){
                for(int j = 0;j<LCDW;j++){
                    Image_Bin[i][j]=0;
                }
            }

           /*涓�甯у浘鍍忔爣蹇椾綅*/
           if(Field_Over_Flag)
           {
               //sprintf((char*)txt,"0000");
               //TFTSPI_P8X8Str(0,4,txt,u16RED,u16BLACK);
               //sprintf((char*)txt,"00000");
               //TFTSPI_P8X8Str(0,5,txt,u16RED,u16BLACK);
               /*瑁佸壀鍥惧儚*/
               Get_Use_Image();

               Image_Binaryzation(Image_RGB565,Image_Bin);
               Pixle_Filter(Image_Bin);


               WhitePoint = Find_area_WhitePoint(0,0,LCDH,LCDW,Image_Bin);
               OV7725_E = Find_offset(Image_Bin);

               //sprintf((char*)txt,"%d",Car_Price.Find_Card);
               //TFTSPI_P8X8Str(0,4,txt,u16RED,u16BLACK);
                           //第六行
               //sprintf((char*)txt,"%d",WhitePoint);
               //TFTSPI_P8X8Str(0,5,txt,u16RED,u16BLACK);

               /*鏄剧ず 120*160*/
               //OV7725_TFTSPI_Road(70, 0, LCDH, LCDW);
               //BIN_OV7725_TFTSPI_Road(70,61,LCDH,LCDW,Image_Bin);

               /*娓呴櫎鏍囧織浣�*/
               Field_Over_Flag = 0;

               if(OV7725_E<7){
                   OV7725_E = 0;
               }

             //  Car_Price.Ture_Error = OV7725_E;
           }
           LED_Ctrl(LED0, RVS);
    }
}

uint8_t B_min = 1,B_max =10 ;
uint8_t G_min = 20,G_max = 120;
uint8_t R_min = 1,R_max = 20;
void Image_Binaryzation(image_RGB565 ppic_in[LCDH][LCDW],uint8_t ppic_out[LCDH][LCDW]){
    for(int i = 0;i<LCDH;i++){
        for(int j = 0;j<LCDW;j++){
            if(ppic_in[i][j].B > B_min && ppic_in[i][j].B < B_max){
                if(ppic_in[i][j].G > G_min && ppic_in[i][j].G < G_max){
                    if(ppic_in[i][j].R > R_min && ppic_in[i][j].R < R_max){
                        ppic_out[i][j]=1;
                    }
                    else{
                        ppic_out[i][j]=0;
                    }
                }
                else{
                    ppic_out[i][j]=0;
                }
            }
            else{
                ppic_out[i][j] = 0;
            }
        }
    }
}

void Pixle_Filter(uint8_t ppic_in[LCDH][LCDW]){
    for(int i = 1;i<LCDH-1;i++){
        for(int j=1;j<LCDW-1;j++){
            if((ppic_in[i][j]==0)&&((ppic_in[i-1][j]+ppic_in[i+1][j]+ppic_in[i][j+1]+ppic_in[i][j-1])>2)){
                ppic_in[i][j] = 1;
            }
            else if(ppic_in[i][j]==1&&(ppic_in[i-1][j]+ppic_in[i+1][j]+ppic_in[i][j-1]+ppic_in[i][j+1]<2)){
                ppic_in[i][j] = 0;
            }
        }
    }

}

int Find_WhitePoint(uint8_t ppic_in[LCDH][LCDW]){
    int sum = 0;
    for(int i = 0;i<LCDH-1;i++){
        for(int j = 1;j<LCDW-1;j++){
            if(ppic_in[i][j] == 1){
                sum++;
            }
        }
    }
    return sum;
}

uint16_t Find_area_WhitePoint(uint8_t start_x,uint8_t start_y,uint8_t stop_x,uint8_t stop_y,uint8_t ppic_in[LCDH][LCDW]){
    uint16_t Point_Value = 0;
    int nr,nc;
    Point_Value = 0;
    for(nr = start_x;nr<stop_x;nr++){
        for(nc = start_y;nc<stop_y;nc++){
            if(ppic_in[nr][nc]==1){
                Point_Value++;
            }
        }
    }
    return Point_Value;
}

float Find_offset(uint8_t ppic_in[LCDH][LCDW]){
    static uint16_t offset = 0;
    uint16_t offset1 = 0,offset2 = 0,offset3 = 0;

    //鐧界偣鏁伴噺
    int WhitePoint_Value = Find_WhitePoint(ppic_in);
    if(WhitePoint_Value>300){
        offset1 = Find_area_WhitePoint(1,1,19,39,ppic_in)
                -Find_area_WhitePoint(1,41,19,79,ppic_in);
        offset2 = Find_area_WhitePoint(21,1,39,39,ppic_in)
                -Find_area_WhitePoint(21,41,39,79,ppic_in);
        offset3 = Find_area_WhitePoint(41,1,59,39,ppic_in)
                -Find_area_WhitePoint(41,41,59,79,ppic_in);

        offset = offset2 + offset1/2 + offset3/2;

        Car_Price.Find_Card = 1;
        Car_Price.Ture_Error = offset;
    }
    else{
        offset = -230;
        Car_Price.Find_Card = 0;
    }
    return (float)offset/10;
}

void OV7725_Task(void){
    extern Car_Price_Typedef Car_Price;
    while(1){
        if(Field_Over_Flag && Car_Price.Flag == 2){   //Field_Over_Flag鏍囪瘑闇�瑕佸幓閲囬泦鏁版嵁浜嗭紝Car_Price.Flag == 2浠ｈ〃鐩墠鏄噰闆嗘暟鎹姸鎬�
            Get_Use_Image();    //灏嗚鍙栧埌鐨勫浘鐗囨暟鎹瓨鍌ㄨ繘Image_RGB565缁撴瀯鏁扮粍涓�
            Image_Binaryzation(Image_RGB565,Image_Bin);    //灏嗚鍙栧埌鐨勬暟鎹簩鍊煎寲锛屽瓨鍏ュ埌Image_Bin涓�

            Pixle_Filter(Image_Bin);    //锛堝幓闄ゅ櫔鐐�

            OV7725_E = Find_offset(Image_Bin);

            Field_Over_Flag = 0;    //Field_Over_Flag浠ｈ〃鏍囧織浣嶈缃负0锛屼唬琛ㄦ暟鎹噰闆嗗畬鎴�
            LED_Ctrl(LED0,RVS);


        }
        else if(Car_Price.Flag!=2){
            delayms(1000);
            LED_Ctrl(LED0,RVS);
        }
        OV7725_TFTSPI_Road(0, 0, LCDH, LCDW);
        BIN_OV7725_TFTSPI_Road(61,81,LCDH,LCDW,Image_Bin);
    }
}









